<template>
  <!-- 画布容器 -->
  <div
    @wheel="handleWheel"

    class="flow-canvas-container"
    ref="canvasContainerRef"
  >
    <!-- 画布 -->
    <div
      class="flow-canvas"
      ref="canvas"
      :style="{
        backgroundImage: `url(${bg})`,
        transform: `translate(${canvasOffset.x}px, ${canvasOffset.y}px) scale(${canvasScale})`,
        transformOrigin: '0 0',
        width: `${canvasSize.width}px`,
        height: `${canvasSize.height}px`,
      }"
    >
      <!-- 连接线容器 -->
      <svg class="connections-container" :width="canvasSize.width" :height="canvasSize.height">
        <g>
          <!-- 所有连接线 -->
          <path
            v-for="connection in connections"
            :key="connection.id"
            :d="getConnectionPathByType(connection)"
            :stroke-width="selectedConnectionId === connection.id ? 5 : 5"
            :stroke="selectedConnectionId === connection.id ? '#000' : '#3b82f6'"
            fill="none"
            class="connection-line"
            @click.stop="selectConnection(connection.id)"
          />
        </g>

        <!-- 临时连接线（正在绘制中） -->
        <path
          v-if="isDrawingConnection"
          :d="getTemporaryConnectionPath()"
          stroke="#666"
          stroke-width="2"
          stroke-dasharray="5,5"
          fill="none"
        />
      </svg>

      <!-- 可拖拽节点 -->
      <div
        v-for="node in nodes"
        :key="node.id"
        class="flow-node"
        :class="{
          resizing: isResizing,
          'connection-source': isDrawingConnection && connectionSourceId === node.id,
        }"
        @dblclick="editNode(node)"
        :style="{
          left: `${node.x}px`,
          top: `${node.y}px`,
          width: `${node.width}px`,
          height: `${node.height}px`,
          backgroundColor: node.color,
          borderRadius: node.type === 'start' ? '50%' : '4px',
        }"
      >
        <slot :node="node" name="content"></slot>
        <slot v-if="node.type === 'slot'" :node="node" :name="node.slotName"></slot>

        <div v-else-if="node.type === 'html'" v-html="node.target"></div>
        <div class="node-label" style="position: absolute; top: -30px">
          {{ node.label }}
        </div>
        <!-- 选中框 -->
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { Plus, Minus } from '@element-plus/icons-vue'
const emit = defineEmits([
  'editNode', // 双击节点触发
]) // 画布缩放和平移状态

// 连线类型（曲线或脑图折线）
const connectionType = ref('curve')

type Props = {
  bg: string //背景图片
  connections: Array<any> //连接线数据
  canvasSize: any
  nodesValue: {
    type: Array
    default: () => []
  }
}
const props = withDefaults(defineProps<Props>(), {
  bg: '',
  canvasSize: { width: 1920, height: 1080 },
  nodesValue: [],
  connections: [],
})
// 双击节点
const editNode = (node) => {
  // 触发编辑事件
  emit('editNode', node)
}
const canvasScale = ref(1)
const canvasOffset = ref({ x: 0, y: 0 })
const canvasSize = ref(props.canvasSize)

// 空格键状态
const spaceKeyPressed = ref(false)
// 画布节点数据
const nodes = ref(props.nodesValue)
const canvas = ref()
const canvasContainerRef = ref()
const canvasSizes = ref(props.canvasSize)
// 强制canvas缩放比例显示全部
const canvasInit = () => {
  // 拿到canvas的父元素的宽高
  const canvasContainer = canvas.value.parentElement
  const canvasContainerWidth = canvasContainer.offsetWidth
  const canvasContainerHeight = canvasContainer.offsetHeight
  // 计算缩放比例
  // 通过canvasContainerWidth，canvasContainerHeight以及canvasSize计算出来宽高 让canvas缩放比例显示全部
  const canvasScale = Math.min(
    canvasContainerWidth / canvasSizes.value.width,
    canvasContainerHeight / canvasSizes.value.height,
  )
  // 设置画布缩放
  canvas.value.style.transform = `scale(${canvasScale})`
  const height = canvasContainer.parentElement.parentElement.parentElement.offsetHeight

  canvasContainerRef.value.style.height = height + 'px'
}

// 连接线数据
const connections = ref(props.connections)
// 根据选择的类型获取连接线路径
const getConnectionPathByType = (connection) => {
  if (connectionType.value === 'mindmap') {
    return getMindmapConnectionPath(connection)
  }
  return getCurveConnectionPath(connection)
}

// 原有曲线连接线路径
const getCurveConnectionPath = (connection) => {
  const sourceCenter = getNodeCenter(connection.source)
  const targetCenter = getNodeCenter(connection.target)

  const midX = (sourceCenter.x + targetCenter.x) / 2

  return `M ${sourceCenter.x} ${sourceCenter.y}
          C ${midX} ${sourceCenter.y},
            ${midX} ${targetCenter.y},
            ${targetCenter.x} ${targetCenter.y}`
}

// 脑图折线连接线路径
const getMindmapConnectionPath = (connection) => {
  const sourceCenter = getNodeCenter(connection.source)
  const targetCenter = getNodeCenter(connection.target)

  // 脑图风格折线：从源节点向右延伸，然后垂直连接到目标节点同一水平位置，再连接到目标节点
  const horizontalOffset = 50 // 水平延伸距离
  const sourceX = sourceCenter.x + horizontalOffset
  const targetX = targetCenter.x > sourceX ? targetCenter.x - horizontalOffset : sourceX

  return `M ${sourceCenter.x} ${sourceCenter.y}
          L ${sourceX} ${sourceCenter.y}
          L ${sourceX} ${targetCenter.y}
          L ${targetCenter.x} ${targetCenter.y}`
}

const getNodeCenter = (nodeId) => {
  const node = nodes.value.find((n) => n.id === nodeId)
  if (!node) return { x: 0, y: 0 }

  return {
    x: node.x + node.width / 2,
    y: node.y + node.height / 2,
  }
}
const handleWheel = (event) => {
  event.preventDefault()
  return
  const rect = canvasContainerRef.value.getBoundingClientRect()
  const mouseX = event.clientX - rect.left
  const mouseY = event.clientY - rect.top

  const contentX = (mouseX - canvasOffset.value.x) / canvasScale.value
  const contentY = (mouseY - canvasOffset.value.y) / canvasScale.value

  const delta = -event.deltaY
  const scaleFactor = delta > 0 ? 1.1 : 0.9
  const newScale = Math.max(0.1, Math.min(5, canvasScale.value * scaleFactor))

  canvasOffset.value.x = mouseX - contentX * newScale
  canvasOffset.value.y = mouseY - contentY * newScale

  canvasScale.value = newScale
}

onMounted(() => {
  nextTick(() => {
    canvasInit()
  })
})
// 根据id设置节点的配置
const setNodesConfig = (id, type, value) => {
  const node = nodes.value.find((n) => n.id === id)
  if (node) {
    // 设置节点的配置
    node[type] = value
    setTimeout(()=>{
      canvasInit()
    })
  }
}
defineExpose({
  setNodesConfig,
  canvasInit
})
</script>

<style>
@import url('./index.css');
</style>
